package com.sailors.common.task.provider.infra.design.common.rest;

import com.sailors.common.task.provider.infra.design.common.util.TryCatchUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceResolvable;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.validation.FieldError;

import java.util.List;
import java.util.Objects;


public class Bru {
    public static final BaseResponse<String> SUCCESS = ofBool(true);
    public static final BaseResponse<String> FAIL = ofBool(false);
    public static MessageSource messageSource;

    public static <T> BaseResponse<T> ofEnum(ReturnCode code) {
        return new BaseResponse<>(null, code.getCode(), getMsg(code));
    }

    public static <T> BaseResponse<T> ofMsg(String msg) {
        return new BaseResponse<>(null, ReturnCode.OPERATION_FAILED.getCode(), msg);
    }

    public static <T> BaseResponse<T> ofMsg(String msg, T data) {
        return new BaseResponse<>(data, ReturnCode.OPERATION_FAILED.getCode(), msg);
    }

    public static <T> BaseResponse<T> ofBool(boolean flag) {
        if (flag) {
            return ofEnum(ReturnCode.SUCCESS);
        } else {
            return ofEnum(ReturnCode.OPERATION_FAILED);
        }
    }

    public static <T> BaseResponse<T> success() {
        return new BaseResponse<>(null, ReturnCode.SUCCESS.getCode(), getMsg(ReturnCode.SUCCESS));
    }

    public static <T> BaseResponse<T> success(T dataInfo) {
        return new BaseResponse<>(dataInfo, ReturnCode.SUCCESS.getCode(), getMsg(ReturnCode.SUCCESS));
    }

    public static <T> BasePageResponse<T> pageOfEnum(ReturnCode code) {
        return new BasePageResponse<>(code.getCode(), getMsg(code));
    }

    public static <T> BasePageResponse<T> pageOfMsg(String msg) {
        return new BasePageResponse<T>(ReturnCode.OPERATION_FAILED.getCode(), msg);
    }

    public static <T> BasePageResponse<T> pageSuccess(Long pageSize, Long pageNumber, Long totalRecord, List<T> records) {
        return new BasePageResponse<T>(ReturnCode.SUCCESS.getCode(), getMsg(ReturnCode.SUCCESS))
                .build(pageSize, pageNumber, totalRecord, records);
    }

    public static <T> BasePageResponse<T> pageOfBool(boolean flag) {
        if (flag) {
            return pageOfEnum(ReturnCode.SUCCESS);
        } else {
            return pageOfEnum(ReturnCode.OPERATION_FAILED);
        }
    }
    /**
     * 获取消息
     * @param code               code
     * @param defaultMessage     默认消息
     * @param args               参数
     * @return 消息
     */
    private static String getMessage(String code, String defaultMessage, Object... args) {
        if (Objects.isNull(messageSource)) {
            return defaultMessage;
        }
        return messageSource.getMessage(new MessageSourceResolvable() {
            @Override
            public String[] getCodes() {
                return new String[]{ code };
            }

            @Override
            public Object[] getArguments() {
                return args;
            }

            @Override
            public String getDefaultMessage() {
                return defaultMessage;
            }
        }, LocaleContextHolder.getLocale());
    }

    /**
     * 参数校验失败
     * @param fieldError fieldError
     * @return Rest
     */
    public static <T> BaseResponse<T> error(FieldError fieldError) {
        String messageKey = fieldError.getDefaultMessage();
        Object[] arguments = fieldError.getArguments();
        String message = getMessage(messageKey, messageKey, arguments);
        return new BaseResponse<T>(null, ReturnCode.PARAM_ILLEGAL.getCode(), message);
    }

    public static String getMsg(ReturnCode code) {
        String message = code.getMsg();
        if (messageSource != null) {
            String localeMessage = TryCatchUtil.tryC(() -> messageSource.getMessage(code.name(), null, LocaleContextHolder.getLocale()));
            if (StringUtils.isNotBlank(localeMessage)) {
                message = localeMessage;
            }
        }
        return message;
    }

}
